package com.zone.vehicle.superapp.model;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.widget.Toast;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.alibaba.fastjson.JSON;
import com.saicmotor.pay.db.PayDaoUtilsStore;
import com.saicmotor.pay.db.entity.Pay;
import com.saicmotor.pay.util.PayUtils;
import com.zone.lib.download.db.DownloadDaoUtilsStore;
import com.zone.lib.download.db.entity.Download;
import com.zone.lib.download.enums.AppStatusEnum;
import com.zone.lib.download.enums.AppTypeEnum;
import com.zone.lib.download.utils.AppStatusUpdateNotify;
import com.zone.lib.download.utils.DownloadUtil;
import com.zone.sdk.common.http.base.Result;
import com.zone.sdk.common.http.callback.ResultCallBack;
import com.zone.sdk.module.account.entity.UserInfoEntity;
import com.zone.sdk.module.appstore.base.AppStoreResult;
import com.zone.sdk.module.appstore.entity.AppDetailEntity;
import com.zone.sdk.module.appstore.entity.AppEntity;
import com.zone.sdk.module.appstore.entity.AppListItemEntity;
import com.saicmotor.pay.entity.OrderEntity;
import com.zone.sdk.module.appstore.entity.UserEntity;
import com.zone.sdk.module.comment.base.CommentPage;
import com.zone.sdk.module.comment.entity.AppCommentScoreEntity;
import com.zone.sdk.module.comment.entity.CommentListEntity;
import com.zone.sdk.module.comment.entity.RecommendEntity;
import com.zone.sdk.module.comment.entity.RecommendListEntity;
import com.zone.sdk.module.comment.entity.SearchResultEntity;
import com.zone.sdk_api.common.Content;
import com.zone.vehicle.sdk.module.superapp.response.AppPushResponse;
import com.zone.vehicle.sdk.module.superapp.vehicle.utils.NetUtil;
import com.zone.vehicle.superapp.bean.AppBean;
import com.zone.vehicle.superapp.bean.RecommendBean;
import com.zone.vehicle.superapp.repository.HomeRepository;
import com.zone.vehicle.superapp.utils.JDUtil;
import com.zone.vehicle.superapp.utils.LoginUtil;
import com.zone.vehicle.superapp.utils.SharedPreferencesUtil;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

import lombok.Data;
import lombok.EqualsAndHashCode;

import static com.zone.vehicle.superapp.common.ContentAccount.ACCESS_TOKEN;

@Data
@EqualsAndHashCode(callSuper = false)
public class HomeViewModel<T extends AppDetailEntity> extends ViewModel {

    private static final String TAG = HomeViewModel.class.getSimpleName();
    private final MutableLiveData<Result> error = new MutableLiveData<>();
    //首页APP list
    private MutableLiveData<AppStoreResult<AppListItemEntity>> appStoreResult = new MutableLiveData<>();
    private MutableLiveData<List<AppListItemEntity>> homeAppList = new MutableLiveData<>();
    //详情页app info
    private MutableLiveData<AppDetailEntity> currentAppEntity = new MutableLiveData<>();
    private MutableLiveData<T> currentApp = new MutableLiveData<>();
    private MutableLiveData<Boolean> payStatus = new MutableLiveData<>();
    //详情页评论
    private MutableLiveData<AppCommentScoreEntity> commentScore = new MutableLiveData<>();
    private MutableLiveData<CommentListEntity> currentCommentList = new MutableLiveData<>();
    //安利墙
    private MutableLiveData<List<RecommendEntity>> recommendList = new MutableLiveData<>();
    private MutableLiveData<List<AppEntity>> recommendAppList = new MutableLiveData<>();
    private MutableLiveData<RecommendBean> recommendBeanList = new MutableLiveData<>();
    //搜索
    private MutableLiveData<String> searchData = new MutableLiveData<>();
    private MutableLiveData<List<SearchResultEntity>> searchAppList = new MutableLiveData<>();
    private MutableLiveData<List<SearchResultEntity>> searchSuggestionsList = new MutableLiveData<>();
    private MutableLiveData<Result<AppPushResponse>> appletPushResponse = new MutableLiveData<>();
    //    private MutableLiveData<Download> currentDownload = new MutableLiveData<>();
    //下单
    private MutableLiveData<UserEntity> userEntity = new MutableLiveData<>();
    private MutableLiveData<AppDetailEntity> currentOrderAppEntity = new MutableLiveData<>();
    //支付
    private MutableLiveData<OrderEntity> orderEntity = new MutableLiveData<>();
    private MutableLiveData<String> payStringInfo = new MutableLiveData<>();
    private MutableLiveData<List<Pay>> payList = new MutableLiveData<>();

    private HomeRepository repository;

    private Handler mIoHandler;

    public HomeViewModel(HomeRepository repository) {
        this.repository = repository;
        init();
    }

    private void init(){
        HandlerThread t = new HandlerThread("download thread");
        t.start();
        mIoHandler = new Handler(t.getLooper());
        setPayList(repository.listPay());
    }

    public MutableLiveData<List<RecommendEntity>> getRecommendList() {
        return recommendList;
    }

    public MutableLiveData<RecommendBean> getRecommendBeanList() {
        return recommendBeanList;
    }

    public MutableLiveData<Result> getError() {
        return error;
    }

    public MutableLiveData<T> getCurrentApp() {
        return currentApp;
    }

    public void setCurrentApp(T currentApp) {
        this.currentApp.setValue(currentApp);
    }

    public MutableLiveData<AppDetailEntity> getCurrentAppEntity() {
        return currentAppEntity;
    }

    public void setCurrentAppEntity(AppDetailEntity appEntity) {
        currentAppEntity.setValue(appEntity);
    }

    public MutableLiveData<Result<AppPushResponse>> getAppletPushResponse() {
        return appletPushResponse;
    }

    public MutableLiveData<AppStoreResult<AppListItemEntity>> getAppStoreResult() {
        return appStoreResult;
    }

    public MutableLiveData<List<AppListItemEntity>> getHomeAppList() {
        return homeAppList;
    }

    public MutableLiveData<CommentListEntity> getCurrentCommentList() {
        return currentCommentList;
    }

    public MutableLiveData<List<AppEntity>> getRecommendAppList() {
        return recommendAppList;
    }

    public MutableLiveData<String> getSearchData() {
        return searchData;
    }

    public void setSearchData(String searchData) {
        this.searchData.setValue(searchData);
    }

    public MutableLiveData<List<SearchResultEntity>> getSearchAppList() {
        return searchAppList;
    }

    public void setSearchAppList(List<SearchResultEntity> searchAppList) {
        this.searchAppList.setValue(searchAppList);
    }

    public MutableLiveData<List<SearchResultEntity>> getSearchSuggestionsList() {
        return searchSuggestionsList;
    }

    public MutableLiveData<AppCommentScoreEntity> getCommentScore() {
        return commentScore;
    }

    public MutableLiveData<List<Pay>> getPayList() {
        return payList;
    }

    public void setPayList(List<Pay> pays) {
        this.payList.setValue(pays);
    }

    public void clearHome() {
        appStoreResult.setValue(null);
        homeAppList.setValue(null);
    }

    @SuppressLint("CheckResult")
    public void getHomeAppListData(Context context) {
//        if (!NetUtil.inspectNet(context)){
//            return;
//        }
        int pageNo = 1;
        if (ObjectUtils.isNotEmpty(appStoreResult.getValue())) {
            AppStoreResult<AppListItemEntity> data = appStoreResult.getValue();
            if (data.getPages() > data.getCurrent()) {
                pageNo = data.getCurrent() + 1;
            } else {
                return;
            }
        }
        repository.getHomeAppListData(pageNo, 50, new ResultCallBack<Result<AppStoreResult<AppListItemEntity>>>() {
            @Override
            public void onSuccess(Result<AppStoreResult<AppListItemEntity>> result) {
//                Log.e(TAG, "onSuccess:"+listAppStoreResult);
                if (ObjectUtils.isNotEmpty(result.getData())) {
                    if (ObjectUtils.isEmpty(appStoreResult.getValue())
                            || (ObjectUtils.isNotEmpty(appStoreResult.getValue())
                            && appStoreResult.getValue().getCurrent() < result.getData().getCurrent())) {
                        appStoreResult.setValue(result.getData());
                        if (ObjectUtils.isNotEmpty(homeAppList.getValue())) {
                            homeAppList.getValue().addAll(result.getData().getRecords());
                        } else {
//                            buildError("1", "home no data");
                            homeAppList.setValue(result.getData().getRecords());
                        }
                    }
                }else {
                    buildError("1", "home no data");
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                Log.e(TAG, "onError:" + errorCode);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void clearSearch() {
        searchAppList.setValue(null);
        searchData.setValue(null);
        searchSuggestionsList.setValue(null);
    }

    public void clearAppDetail() {
        currentApp.setValue(null);
        currentCommentList.setValue(null);
        commentScore.setValue(null);
    }

    public void getAppDetail(Context context) {

        AppDetailEntity appEntity = currentAppEntity.getValue();
        if (ObjectUtils.isEmpty(appEntity)) {
            return;
        }
        clearAppDetail();
        mIoHandler.post(new Runnable() {
            @Override
            public void run() {

                repository.getAppDetail(context, appEntity.getCode(), new ResultCallBack<Result<AppDetailEntity>>() {
                    @Override
                    public void onSuccess(Result<AppDetailEntity> result) {
//                Log.e(TAG, "onSuccess:"+result);
                        AppDetailEntity appEntity1 = result.getData();
                        if (result.getResultCode().equals("200") && ObjectUtils.isNotEmpty(appEntity1)) {
                            appEntity1.setProductPrice(appEntity.getProductPrice());
                            AppBean appBean = new AppBean();
                            appBean.build(appEntity1);
                            Download download = null;
                            if (appEntity1.needPay()){
                                //付费
                                if (LoginUtil.isLogin()){
                                    //登录
                                    Pay pay = PayDaoUtilsStore.getInstance().getPayByCode(appEntity1.getCode(), LoginUtil.getUserId());
                                    appBean.setPay(pay);
                                    if (ObjectUtils.isNotEmpty(pay) && pay.getPayStatus().equals("1")){
                                        download = DownloadDaoUtilsStore.getInstance().getDownloadByCode(appEntity.getCode());
                                    }
                                }
                            }else {
                                download = DownloadDaoUtilsStore.getInstance().getDownloadByCode(appEntity.getCode());
                            }
                            appBean.setDownload(download);
                            currentApp.setValue((T) appBean);
                            getCommentListData(result.getData());
                            commentCommentScore(result.getData());
                        } else {
                            buildError(result.getResultCode(), result.getResultMsg());
                        }
                    }

                    @Override
                    public void onError(String errorCode, String message) {
                        buildError(errorCode, message);
                    }

                    @Override
                    public void onComplete() {

                    }
                });

            }
        });
    }

    public void commentCommentScore(AppDetailEntity appEntity) {
        repository.commentScore(appEntity.getCode(), new ResultCallBack<Result<AppCommentScoreEntity>>() {
            @Override
            public void onSuccess(Result<AppCommentScoreEntity> commentScoreEntityResult) {
                commentScore.setValue(commentScoreEntityResult.getData());
            }

            @Override
            public void onError(String errorCode, String message) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void getCommentListData(AppDetailEntity appEntity) {
        repository.commentList(appEntity.getCode(), new ResultCallBack<Result<CommentListEntity>>() {
            @Override
            public void onSuccess(Result<CommentListEntity> result) {
//                Log.e(TAG, "onSuccess:"+result);
                if (result.getResultCode().equals("200") && ObjectUtils.isNotEmpty(result.getData())) {
                    currentCommentList.setValue(result.getData());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                Log.e(TAG, "errorCode:" + errorCode);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void commentInitAmwayWallList() {
        repository.commentInitAmwayWallList(new ResultCallBack<Result<RecommendListEntity>>() {
            @Override
            public void onSuccess(Result<RecommendListEntity> pageResultResult) {
                Log.e(TAG, "getRecommendListData onSuccess:" + pageResultResult);
                recommendList.setValue(pageResultResult.getData().getDataList());
                getRecommendApp(pageResultResult.getData().getDataList());
            }

            @Override
            public void onError(String errorCode, String message) {
                Log.e(TAG, "getRecommendListData onError:" + errorCode);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void downLoadApp(Context context, int status) {
        T appEntity = getCurrentApp().getValue();
        if (appEntity != null && StringUtils.isNotEmpty(appEntity.getAppType()) && appEntity.getAppType().equals(AppTypeEnum.APP_LIGHT.getName())) {
            appletPush(context, appEntity, AppStatusEnum.DOWNLOAD_PREPARE);
        } else if (appEntity != null && StringUtils.isNotEmpty(appEntity.getAppType()) && appEntity.getAppType().equals(AppTypeEnum.APP.getName())) {
            repository.downLoadApp(context, status, appEntity);
        }
    }

    public UserEntity buildUserEntity(Context context) {
        String token = SharedPreferencesUtil.getInstance(context).getSP(ACCESS_TOKEN);
        if (token == null || token.isEmpty()) {
            return null;
        }
        UserEntity entity = new UserEntity();
        entity.setAccessToken(token);
        Object o = SharedPreferencesUtil.getInstance(context).getObject(Content.USER_INFO, UserInfoEntity.class);
        if (ObjectUtils.isEmpty(o)) {
            Log.w(TAG, "build user entity error of null user info ");
            return null;
        }
        UserInfoEntity userInfoEntity = (UserInfoEntity) o;
        entity.setUserId(userInfoEntity.getId());
        entity.setNick(userInfoEntity.getNickname());
        return entity;
    }

    private void appletPush(Context context, AppDetailEntity appEntity, AppStatusEnum statusEnum) {
        Download download = DownloadDaoUtilsStore.getInstance().getDownloadByCode(appEntity.getCode());
        if (download == null) {
            download = DownloadUtil.build(statusEnum.CODE, appEntity, null);
            DownloadDaoUtilsStore.getInstance().getDownloadAppDaoUtils().insert(download);
        }
        repository.appletPush(context, appEntity, statusEnum, new ResultCallBack<Result<AppPushResponse>>() {
            @Override
            public void onSuccess(Result<AppPushResponse> result) {
                appletPushResponse.setValue(result);
                Download download = DownloadDaoUtilsStore.getInstance().getDownloadByCode(appEntity.getCode());
                if (result.getResultCode().equals("200")) {
                    if (statusEnum == AppStatusEnum.LIGHT_DELETE
                            || statusEnum == AppStatusEnum.UNINSTALL_APP_AND_LIGHT) {
                        download.setDownloadStatus(AppStatusEnum.LIGHT_DELETE_SUCCESS.CODE);
                        DownloadDaoUtilsStore.getInstance().getDownloadAppDaoUtils().delete(download);
                    } else {
                        download.setDownloadStatus(AppStatusEnum.LIGHT_INSTALL_COMPLETE.CODE);
                    }
                } else {
                    if (statusEnum == AppStatusEnum.LIGHT_DELETE
                            || statusEnum == AppStatusEnum.UNINSTALL_APP_AND_LIGHT) {
                        download.setDownloadStatus(AppStatusEnum.LIGHT_DELETE_FAILED.CODE);
                    } else {
                        download.setDownloadStatus(AppStatusEnum.LIGHT_INSTALL_FAIL.CODE);
                    }
                    buildError(result.getResultCode(), result.getResultMsg());
                }
                AppStatusUpdateNotify.appNotify(context, download);
            }

            @Override
            public void onError(String errorCode, String message) {
                Download download = DownloadDaoUtilsStore.getInstance().getDownloadByCode(appEntity.getCode());
                if (statusEnum == AppStatusEnum.LIGHT_DELETE
                        || statusEnum == AppStatusEnum.UNINSTALL_APP_AND_LIGHT) {
                    download.setDownloadStatus(AppStatusEnum.LIGHT_DELETE_FAILED.CODE);
                } else {
                    download.setDownloadStatus(AppStatusEnum.LIGHT_INSTALL_FAIL.CODE);
                }
                AppStatusUpdateNotify.appNotify(context, download);
                buildError(errorCode, message);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void startApp(Context context, AppBean appBean) {
        if (appBean.getStatusDictionaryType().equals(AppTypeEnum.APP_LIGHT.getName())) {
            JDUtil.start(context, appBean.getCode(), appBean.getAppType());
        } else if (appBean.getAppType().equals(AppTypeEnum.APP.getName())) {
            Intent intent = context.getPackageManager().getLaunchIntentForPackage(appBean.getPackageName());
            if (intent != null) {
                intent.setPackage(null);
                context.startActivity(intent);
            }
        }
    }

    public void submitOrder(Context context, AppBean appBean, UserEntity userEntity, Runnable successRunnable) {
//        setUserEntity(userEntity);
//        setCurrentOrderAppEntity(appBean);
//        OrderEntity entity = new OrderEntity();
//        entity.setMerchOrderId("112");
//        entity.setTransNo("134");
//        setOrderEntity(entity);
//        successRunnable.run();
        clearPayStatus();
        repository.submitOrder(context, PayUtils.SOURCE_SUPPER_APP,appBean, userEntity, new ResultCallBack<Result<OrderEntity>>() {
            @Override
            public void onSuccess(Result<OrderEntity> orderEntityResult) {
                OrderEntity entity = orderEntityResult.getData();
                if (ObjectUtils.isEmpty(entity)) {
                    Log.e(TAG, "fail submit order null response data");
                    Toast.makeText(context, "订单提交失败", Toast.LENGTH_SHORT).show();
                    return;
                }
                setUserEntity(userEntity);
                setCurrentOrderAppEntity(appBean);
                setOrderEntity(entity);
                successRunnable.run();
            }

            @Override
            public void onError(String errorCode, String message) {
                Log.e(TAG, "fail submit order with error " + errorCode + "  " + message);
                Toast.makeText(context, "订单提交失败", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onComplete() {

            }
        });
    }

    private void getRecommendApp(List<RecommendEntity> recommendEntityList) {
        if (ObjectUtils.isEmpty(recommendEntityList)) {
            return;
        }

//        List<String> appIds = recommendEntityList.stream().map(RecommendEntity::getObjectId).collect(Collectors.toList());
        List<String> appIds = new ArrayList<>();
        for (int i = 0; i < recommendEntityList.size(); i++) {
            appIds.add(recommendEntityList.get(i).getObjectId());
        }
        if (ObjectUtils.isNotEmpty(appIds)) {
            repository.appList(appIds, new ResultCallBack<Result<List<AppEntity>>>() {
                @Override
                public void onSuccess(Result<List<AppEntity>> result) {
                    Log.e(TAG, "recommendAppList onSuccess:" + result);
                    recommendAppList.setValue(result.getData());
                    RecommendBean recommendBean = new RecommendBean();
                    recommendBean.setAppEntityList(result.getData());
                    recommendBean.setRecommendEntityList(recommendEntityList);
                    recommendBeanList.setValue(recommendBean);
                }

                @Override
                public void onError(String errorCode, String message) {
                    Log.e(TAG, "getRecommendListData onError:" + errorCode);
                }

                @Override
                public void onComplete() {
                }
            });
        }
    }

    public void searchSuggestions(String search) {
        if (StringUtils.isEmpty(search)) {
            searchSuggestionsList.setValue(null);
            return;
        }
        repository.indexSearch(search, new ResultCallBack<Result<CommentPage<SearchResultEntity>>>() {
            @Override
            public void onSuccess(Result<CommentPage<SearchResultEntity>> result) {
                if (result.getResultCode().equals("200")
                        && result.getData().getPageCount() > 0
                ) {
                    searchSuggestionsList.setValue(result.getData().getDataList());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                buildError(errorCode, message);
            }

            @Override
            public void onComplete() {
            }
        });
    }

    public void indexSearch(Context context, String search) {
        if (StringUtils.isEmpty(search)) {
            searchAppList.setValue(null);
            return;
        }
        if (!NetUtil.inspectNet(context)) {
            return;
        }
        repository.indexSearch(search, new ResultCallBack<Result<CommentPage<SearchResultEntity>>>() {
            @Override
            public void onSuccess(Result<CommentPage<SearchResultEntity>> result) {
                if (result.getResultCode().equals("200")) {
                    List<SearchResultEntity> resultEntityList = result.getData().getDataList();
                    if (ObjectUtils.isNotEmpty(resultEntityList)) {
                        for (int i = 0; i < resultEntityList.size(); i++) {
                            SearchResultEntity entity = resultEntityList.get(i);
                            repository.getAppDetail(context, entity.getGoodsCode(), new ResultCallBack<Result<AppDetailEntity>>() {
                                @Override
                                public void onSuccess(Result<AppDetailEntity> appEntityResult) {
                                    if (result.getResultCode().equals("200")) {
                                        AppDetailEntity appEntity = appEntityResult.getData();
                                        if (ObjectUtils.isNotEmpty(appEntity)) {
                                            List<SearchResultEntity> entities = searchAppList.getValue();
                                            List<SearchResultEntity> temp = new ArrayList<>();
                                            if (ObjectUtils.isNotEmpty(entities)) {
                                                for (SearchResultEntity entity : entities) {
                                                    if (entity.getGoodsCode().equals(appEntity.getCode())) {
                                                        entity.setDownloadsNum("" + appEntity.getDownloadCount());
                                                    }
                                                    temp.add(entity);
                                                }
                                                searchAppList.setValue(temp);
                                            }

                                        }
                                    }
                                }

                                @Override
                                public void onError(String errorCode, String message) {

                                }

                                @Override
                                public void onComplete() {

                                }
                            });
                        }
                    }
                    searchAppList.setValue(result.getData().getDataList());
                } else {
                    buildError(result.getResultCode(), result.getResultMsg());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                buildError(errorCode, message);
            }

            @Override
            public void onComplete() {
            }
        });
    }

    public void install(Context context, AppStatusEnum appStatusEnum) {
        T appEntity = getCurrentApp().getValue();
        if (ObjectUtils.isNotEmpty(appEntity)) {
            if (appEntity.getAppType().equals(AppTypeEnum.APP.getName())) {
                repository.install(context, appEntity, appStatusEnum);
            } else if (appEntity.getAppType().equals(AppTypeEnum.APP_LIGHT.getName())) {
                appletPush(context, appEntity, appStatusEnum);
            }
        }
    }

    private void buildError(String errorCode, String message) {
        Log.e(TAG, errorCode + message);
        Result result = new Result();
        result.setResultCode(errorCode);
        result.setResultMsg(message);
        error.setValue(result);
    }

    public MutableLiveData<OrderEntity> getOrderEntity() {
        return orderEntity;
    }

    public void setOrderEntity(OrderEntity orderEntity) {
        this.orderEntity.setValue(orderEntity);
    }

    public AppDetailEntity getCurrentOrderAppEntity() {
        return currentOrderAppEntity.getValue();
    }

    public void setCurrentOrderAppEntity(AppBean currentOrderAppEntity) {
        this.currentOrderAppEntity.setValue(currentOrderAppEntity);
    }

    public void clearPayInfo() {
        this.orderEntity.setValue(null);
        this.payStringInfo.setValue(null);
    }

    public MutableLiveData<UserEntity> getUserEntity() {
        return userEntity;
    }

    public void setUserEntity(UserEntity userEntity) {
        this.userEntity.setValue(userEntity);
    }

    public String getPayStringInfo() {
        return payStringInfo.getValue();
    }

    public void setPayStringInfo(String payStringInfo) {
        this.payStringInfo.setValue(payStringInfo);
    }

    public Boolean getPayStatus() {
        return payStatus.getValue();
    }

    public void setPayStatus(Boolean payStatus) {
        this.payStatus.setValue(payStatus);
    }

    public void clearPayStatus() {
        this.payStatus.setValue(null);
        this.orderEntity.setValue(null);
        this.payStringInfo.setValue(null);
        this.currentOrderAppEntity.setValue(null);
    }
}